package com.doctracker.controller;

import com.doctracker.model.Person;
import com.doctracker.model.ScanResult;
import com.doctracker.service.ExcelService;
import com.doctracker.service.ExcelTemplateService;
import com.doctracker.service.FileScanner;
import com.doctracker.service.DataManager;
import com.doctracker.service.FileRenameService;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.Modality;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.Parent;
import javafx.scene.image.Image;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;

/**
 * 主界面控制器类
 * 负责处理用户界面的所有交互逻辑
 */
public class MainController implements Initializable {
    
    // ===== FXML 注入的界面元素 =====
    
    // 按钮控件
    @FXML private Button downloadTemplateButton;
    @FXML private Button importExcelButton;
    @FXML private Button loadHistoryButton;
    @FXML private Button savePeopleButton;
    @FXML private Button clearPeopleButton;
    @FXML private Button addFolderButton;
    @FXML private Button removeFolderButton;
    @FXML private Button scanButton;
    @FXML private Button addPersonButton;
    @FXML private Button removePersonButton;
    @FXML private Button renameFilesButton;
    @FXML private Button exportAllButton;
    @FXML private Button exportUnsubmittedButton;
    
    // 列表控件
    @FXML private ListView<Person> peopleListView;
    @FXML private ListView<String> foldersListView;
    @FXML private ListView<String> resultsListView;
    
    // 标签控件
    @FXML private Label peopleCountLabel;
    @FXML private Label statisticsLabel;
    @FXML private Label statusLabel;
    
    // 进度指示器
    @FXML private ProgressIndicator progressIndicator;
    
    // ===== 数据模型 =====
    
    /**
     * 人员列表数据
     */
    private ObservableList<Person> peopleData = FXCollections.observableArrayList();
    
    /**
     * 扫描文件夹列表数据
     */
    private ObservableList<String> foldersData = FXCollections.observableArrayList();
    
    /**
     * 扫描结果列表数据
     */
    private ObservableList<String> resultsData = FXCollections.observableArrayList();
    
    // ===== 服务类 =====
    
    /**
     * Excel导入服务
     */
    private ExcelService excelService = new ExcelService();
    
    /**
     * 文件扫描服务
     */
    private FileScanner fileScanner = new FileScanner();
    
    /**
     * 数据管理服务
     */
    private DataManager dataManager = new DataManager();
    
    /**
     * 文件改名服务
     */
    private FileRenameService fileRenameService = new FileRenameService();
    
    /**
     * Excel模板生成服务
     */
    private ExcelTemplateService excelTemplateService = new ExcelTemplateService();
    
    /**
     * 最近一次扫描结果
     */
    private ScanResult lastScanResult;
    
    /**
     * 初始化方法
     * 在FXML加载完成后自动调用
     */
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        System.out.println("初始化主界面控制器");
        
        // 绑定数据到列表视图
        setupListViews();
        
        // 设置自定义单元格渲染
        setupCellFactories();
        
        // 更新界面状态
        updateUI();
        
        // 设置状态
        updateStatus("程序已启动，请导入人员名单或添加扫描文件夹");
    }
    
    /**
     * 设置列表视图的数据绑定
     */
    private void setupListViews() {
        // 绑定人员列表
        peopleListView.setItems(peopleData);
        
        // 绑定文件夹列表
        foldersListView.setItems(foldersData);
        
        // 绑定结果列表
        resultsListView.setItems(resultsData);
    }
    
    /**
     * 设置列表视图的自定义单元格渲染
     */
    private void setupCellFactories() {
        // 设置人员列表的单元格渲染
        peopleListView.setCellFactory(listView -> new ListCell<Person>() {
            @Override
            protected void updateItem(Person person, boolean empty) {
                super.updateItem(person, empty);
                
                if (empty || person == null) {
                    setText(null);
                    setStyle("");
                } else {
                    setText(person.getDisplayText());
                    
                    // 根据提交状态设置样式
                    if (person.isHasSubmitted()) {
                        setStyle("-fx-text-fill: #2e7d32; -fx-background-color: #e8f5e8;");
                    } else {
                        setStyle("-fx-text-fill: #c62828; -fx-background-color: #ffebee;");
                    }
                }
            }
        });
    }
    
    // ===== 事件处理方法 =====
    
    /**
     * 处理下载模板按钮点击事件
     */
    @FXML
    private void handleDownloadTemplate() {
        System.out.println("点击下载模板按钮");
        
        try {
            // 创建文件保存对话框
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("保存Excel模板");
            fileChooser.setInitialFileName(excelTemplateService.generateDefaultFileName());
            fileChooser.getExtensionFilters().add(
                new FileChooser.ExtensionFilter("Excel文件", "*.xlsx")
            );
            
            // 显示保存对话框
            Stage stage = (Stage) downloadTemplateButton.getScene().getWindow();
            File saveFile = fileChooser.showSaveDialog(stage);
            
            if (saveFile != null) {
                updateStatus("正在生成模板...");
                
                // 生成模板
                boolean success = excelTemplateService.generateTemplate(saveFile);
                
                if (success) {
                    updateStatus("模板生成成功: " + saveFile.getName());
                    showInfo("模板下载", 
                        "Excel模板已保存到:\n" + saveFile.getAbsolutePath() + 
                        "\n\n请在模板中填写学生姓名，然后使用\"导入Excel名单\"功能导入。");
                    
                    // 尝试打开文件所在文件夹
                    try {
                        java.awt.Desktop.getDesktop().open(saveFile.getParentFile());
                    } catch (Exception e) {
                        System.out.println("无法打开文件夹: " + e.getMessage());
                    }
                } else {
                    updateStatus("模板生成失败");
                    showError("生成失败", "无法生成Excel模板，请检查文件路径是否有效。");
                }
            }
            
        } catch (Exception e) {
            updateStatus("模板生成失败");
            showError("生成失败", "生成Excel模板时发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 处理导入Excel按钮点击事件
     */
    @FXML
    private void handleImportExcel() {
        System.out.println("点击导入Excel按钮");
        
        // 创建文件选择器
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择Excel文件");
        fileChooser.getExtensionFilters().addAll(
            new FileChooser.ExtensionFilter("Excel文件", "*.xlsx", "*.xls"),
            new FileChooser.ExtensionFilter("所有文件", "*.*")
        );
        
        // 显示文件选择对话框
        File selectedFile = fileChooser.showOpenDialog(importExcelButton.getScene().getWindow());
        
        if (selectedFile != null) {
            importExcelFile(selectedFile);
        }
    }
    
    /**
     * 导入Excel文件
     * 
     * @param excelFile Excel文件
     */
    private void importExcelFile(File excelFile) {
        // 显示进度指示器
        showProgress("正在导入Excel文件...");
        
        // 在后台线程中执行导入
        Task<List<Person>> importTask = new Task<List<Person>>() {
            @Override
            protected List<Person> call() throws Exception {
                return excelService.importFromExcel(excelFile);
            }
            
            @Override
            protected void succeeded() {
                List<Person> importedPeople = getValue();
                
                // 在UI线程中更新界面
                Platform.runLater(() -> {
                    // 询问用户是否替换现有数据
                    if (!peopleData.isEmpty()) {
                        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                        alert.setTitle("导入确认");
                        alert.setHeaderText("检测到 " + importedPeople.size() + " 个人员");
                        alert.setContentText("当前已有 " + peopleData.size() + " 个人员，是否替换？");
                        
                        ButtonType replaceButton = new ButtonType("替换现有");
                        ButtonType appendButton = new ButtonType("追加到现有");
                        ButtonType cancelButton = new ButtonType("取消", ButtonBar.ButtonData.CANCEL_CLOSE);
                        
                        alert.getButtonTypes().setAll(replaceButton, appendButton, cancelButton);
                        
                        Optional<ButtonType> result = alert.showAndWait();
                        
                        if (result.isPresent()) {
                            if (result.get() == replaceButton) {
                                // 替换现有数据
                                peopleData.clear();
                                peopleData.addAll(importedPeople);
                            } else if (result.get() == appendButton) {
                                // 追加到现有数据
                                peopleData.addAll(importedPeople);
                            }
                            // 取消则什么都不做
                        }
                    } else {
                                            // 直接添加到空列表
                    peopleData.addAll(importedPeople);
                }
                
                updateUI();
                hideProgress();
                updateStatus("成功导入 " + importedPeople.size() + " 个人员");
                });
            }
            
            @Override
            protected void failed() {
                Platform.runLater(() -> {
                    hideProgress();
                    showError("导入Excel失败", getException().getMessage());
                });
            }
        };
        
        // 启动后台任务
        new Thread(importTask).start();
    }
    
    /**
     * 处理加载历史名单按钮点击事件
     */
    @FXML
    private void handleLoadHistory() {
        // 获取历史名单列表
        List<DataManager.HistoryItem> historyList = dataManager.getHistoryList();
        
        if (historyList.isEmpty()) {
            showInfo("无历史记录", "暂无保存的历史名单，请先保存一个名单。");
            return;
        }
        
        // 创建选择对话框
        ChoiceDialog<DataManager.HistoryItem> dialog = new ChoiceDialog<>(historyList.get(0), historyList);
        dialog.setTitle("选择历史名单");
        dialog.setHeaderText("请选择要加载的历史名单");
        dialog.setContentText("历史名单:");
        
        // 设置对话框图标
        setDialogIcon(dialog);
        
        Optional<DataManager.HistoryItem> result = dialog.showAndWait();
        if (result.isPresent()) {
            DataManager.HistoryItem selectedItem = result.get();
            loadHistoryList(selectedItem);
        }
    }
    
    /**
     * 加载历史名单
     * 
     * @param historyItem 历史记录项
     */
    private void loadHistoryList(DataManager.HistoryItem historyItem) {
        showProgress("正在加载历史名单...");
        
        Task<List<Person>> loadTask = new Task<List<Person>>() {
            @Override
            protected List<Person> call() throws Exception {
                return dataManager.loadPeopleList(historyItem.getFileName());
            }
            
            @Override
            protected void succeeded() {
                List<Person> loadedPeople = getValue();
                
                Platform.runLater(() -> {
                    if (!loadedPeople.isEmpty()) {
                        // 询问用户是否替换现有数据
                        if (!peopleData.isEmpty()) {
                            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                            alert.setTitle("加载确认");
                            alert.setHeaderText("加载历史名单: " + historyItem.getName());
                            alert.setContentText("当前已有 " + peopleData.size() + " 个人员，是否替换？");
                            
                            ButtonType replaceButton = new ButtonType("替换现有");
                            ButtonType appendButton = new ButtonType("追加到现有");
                            ButtonType cancelButton = new ButtonType("取消", ButtonBar.ButtonData.CANCEL_CLOSE);
                            
                            alert.getButtonTypes().setAll(replaceButton, appendButton, cancelButton);
                            
                            Optional<ButtonType> choice = alert.showAndWait();
                            
                            if (choice.isPresent()) {
                                if (choice.get() == replaceButton) {
                                    peopleData.clear();
                                    peopleData.addAll(loadedPeople);
                                } else if (choice.get() == appendButton) {
                                    peopleData.addAll(loadedPeople);
                                }
                            }
                        } else {
                            peopleData.addAll(loadedPeople);
                        }
                        
                        updateUI();
                        updateStatus("成功加载历史名单: " + historyItem.getName() + " (" + loadedPeople.size() + "人)");
                    } else {
                        showError("加载失败", "无法加载历史名单，文件可能已损坏。");
                    }
                    
                    hideProgress();
                });
            }
            
            @Override
            protected void failed() {
                Platform.runLater(() -> {
                    hideProgress();
                    showError("加载失败", "加载历史名单时发生错误: " + getException().getMessage());
                });
            }
        };
        
        new Thread(loadTask).start();
    }
    
    /**
     * 处理保存人员名单按钮点击事件
     */
    @FXML
    private void handleSavePeople() {
        if (peopleData.isEmpty()) {
            showInfo("无数据", "人员名单为空，无法保存。");
            return;
        }
        
        // 输入名单名称对话框
        TextInputDialog dialog = new TextInputDialog();
        dialog.setTitle("保存名单");
        dialog.setHeaderText("保存当前人员名单");
        dialog.setContentText("请输入名单名称:");
        
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent()) {
            String listName = result.get().trim();
            if (!listName.isEmpty()) {
                saveCurrentPeopleList(listName);
            } else {
                showInfo("名称无效", "名单名称不能为空。");
            }
        }
    }
    
    /**
     * 保存当前人员名单
     * 
     * @param listName 名单名称
     */
    private void saveCurrentPeopleList(String listName) {
        showProgress("正在保存名单...");
        
        Task<Boolean> saveTask = new Task<Boolean>() {
            @Override
            protected Boolean call() throws Exception {
                return dataManager.savePeopleList(new ArrayList<>(peopleData), listName);
            }
            
            @Override
            protected void succeeded() {
                Boolean success = getValue();
                
                Platform.runLater(() -> {
                    hideProgress();
                    if (success) {
                        updateStatus("名单保存成功: " + listName + " (" + peopleData.size() + "人)");
                        showInfo("保存成功", "名单已保存: " + listName + "\n人员数量: " + peopleData.size());
                    } else {
                        showError("保存失败", "保存名单时发生错误，请重试。");
                    }
                });
            }
            
            @Override
            protected void failed() {
                Platform.runLater(() -> {
                    hideProgress();
                    showError("保存失败", "保存名单时发生错误: " + getException().getMessage());
                });
            }
        };
        
        new Thread(saveTask).start();
    }
    
    /**
     * 处理清空人员名单按钮点击事件
     */
    @FXML
    private void handleClearPeople() {
        if (!peopleData.isEmpty()) {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.setTitle("确认清空");
            alert.setHeaderText("清空人员名单");
            alert.setContentText("确定要清空所有人员名单吗？此操作不可撤销。");
            
            Optional<ButtonType> result = alert.showAndWait();
            if (result.isPresent() && result.get() == ButtonType.OK) {
                peopleData.clear();
                resultsData.clear();
                updateUI();
                updateStatus("已清空人员名单");
            }
        }
    }
    
    /**
     * 处理添加文件夹按钮点击事件
     */
    @FXML
    private void handleAddFolder() {
        // 创建文件夹选择器
        DirectoryChooser directoryChooser = new DirectoryChooser();
        directoryChooser.setTitle("选择要扫描的文件夹");
        
        // 显示文件夹选择对话框
        File selectedFolder = directoryChooser.showDialog(addFolderButton.getScene().getWindow());
        
        if (selectedFolder != null) {
            String folderPath = selectedFolder.getAbsolutePath();
            
            // 检查是否已经添加过
            if (!foldersData.contains(folderPath)) {
                foldersData.add(folderPath);
                updateUI(); // 更新按钮状态
                updateStatus("已添加扫描文件夹: " + folderPath);
            } else {
                showInfo("文件夹已存在", "该文件夹已经在扫描列表中");
            }
        }
    }
    
    /**
     * 处理移除文件夹按钮点击事件
     */
    @FXML
    private void handleRemoveFolder() {
        String selectedFolder = foldersListView.getSelectionModel().getSelectedItem();
        
        if (selectedFolder != null) {
            foldersData.remove(selectedFolder);
            updateStatus("已移除扫描文件夹: " + selectedFolder);
        } else {
            showInfo("未选择文件夹", "请先选择要移除的文件夹");
        }
    }
    
    /**
     * 处理开始扫描按钮点击事件
     */
    @FXML
    private void handleScan() {
        // 验证扫描条件
        if (peopleData.isEmpty()) {
            showInfo("无人员数据", "请先导入人员名单");
            return;
        }
        
        if (foldersData.isEmpty()) {
            showInfo("无扫描文件夹", "请先添加要扫描的文件夹");
            return;
        }
        
        // 开始扫描
        startScan();
    }
    
    /**
     * 开始扫描文件
     */
    private void startScan() {
        showProgress("正在扫描文件...");
        
        // 创建后台扫描任务
        Task<ScanResult> scanTask = new Task<ScanResult>() {
            @Override
            protected ScanResult call() throws Exception {
                List<String> folders = new ArrayList<>(foldersData);
                List<Person> people = new ArrayList<>(peopleData);
                
                return fileScanner.scanFolders(folders, people);
            }
            
            @Override
            protected void succeeded() {
                ScanResult result = getValue();
                
                Platform.runLater(() -> {
                    // 保存扫描结果
                    lastScanResult = result;
                    
                    // 更新人员数据
                    peopleData.clear();
                    peopleData.addAll(result.getPeople());
                    
                    // 更新结果显示
                    updateScanResults(result);
                    
                    hideProgress();
                    updateStatus("扫描完成: " + result.getSummaryText());
                });
            }
            
            @Override
            protected void failed() {
                Platform.runLater(() -> {
                    hideProgress();
                    showError("扫描失败", getException().getMessage());
                });
            }
        };
        
        // 启动后台任务
        new Thread(scanTask).start();
    }
    
    /**
     * 更新扫描结果显示
     * 
     * @param result 扫描结果
     */
    private void updateScanResults(ScanResult result) {
        // 清空结果列表
        resultsData.clear();
        
        // 添加已提交人员（显示文件夹信息）
        for (Person person : result.getSubmittedPeople()) {
            String folderName = person.getFolderName();
            if (folderName != null && !folderName.isEmpty()) {
                resultsData.add("✅ " + person.getName() + " - " + person.getFileName() + " (" + folderName + ")");
            } else {
                resultsData.add("✅ " + person.getName() + " - " + person.getFileName());
            }
        }
        
        // 添加未提交人员
        for (Person person : result.getUnsubmittedPeople()) {
            resultsData.add("❌ " + person.getName() + " - 未找到文件");
        }
        
        // 更新统计信息
        updateUI();
    }
    
    /**
     * 处理手动添加人员按钮点击事件
     */
    @FXML
    private void handleAddPerson() {
        TextInputDialog dialog = new TextInputDialog();
        dialog.setTitle("添加人员");
        dialog.setHeaderText("手动添加人员");
        dialog.setContentText("请输入姓名:");
        
        Optional<String> result = dialog.showAndWait();
        if (result.isPresent()) {
            String name = result.get().trim();
            if (!name.isEmpty()) {
                Person person = new Person(name);
                peopleData.add(person);
                updateUI();
                updateStatus("已添加人员: " + name);
            }
        }
    }
    
    /**
     * 处理删除选中人员按钮点击事件
     */
    @FXML
    private void handleRemovePerson() {
        Person selectedPerson = peopleListView.getSelectionModel().getSelectedItem();
        
        if (selectedPerson != null) {
            peopleData.remove(selectedPerson);
            updateUI();
            updateStatus("已删除人员: " + selectedPerson.getName());
        } else {
            showInfo("未选择人员", "请先选择要删除的人员");
        }
    }
    
    /**
     * 处理导出详细报告按钮点击事件
     */
    @FXML
    private void handleExportAll() {
        if (lastScanResult == null) {
            showInfo("无扫描结果", "请先执行扫描操作");
            return;
        }
        
        exportReport(false);
    }
    
    /**
     * 处理导出未提交名单按钮点击事件
     */
    @FXML
    private void handleExportUnsubmitted() {
        if (lastScanResult == null) {
            showInfo("无扫描结果", "请先执行扫描操作");
            return;
        }
        
        exportReport(true);
    }
    
    /**
     * 处理一键改名按钮点击事件
     */
    @FXML
    private void handleRenameFiles() {
        if (lastScanResult == null || lastScanResult.getSubmittedPeople().isEmpty()) {
            showInfo("无匹配文件", "请先扫描并确保有已匹配的文件");
            return;
        }
        
        // 获取可用字段
        java.util.Set<String> availableFields = fileRenameService.getAvailableFields(lastScanResult.getPeople());
        
        if (availableFields.size() <= 1) { // 只有"姓名"字段
            showInfo("字段不足", "当前只有姓名字段，请导入包含更多字段的Excel文件");
            return;
        }
        
        // 显示改名规则设置对话框
        showRenameDialog(availableFields, lastScanResult.getSubmittedPeople());
    }
    
    /**
     * 显示改名规则设置对话框
     * 
     * @param availableFields 可用字段
     * @param submittedPeople 已提交文件的人员列表
     */
    private void showRenameDialog(java.util.Set<String> availableFields, java.util.List<Person> submittedPeople) {
        try {
            // 加载FXML
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/rename-dialog.fxml"));
            Parent root = loader.load();
            
            // 获取控制器
            RenameDialogController controller = loader.getController();
            
            // 创建新窗口
            Stage dialogStage = new Stage();
            dialogStage.setTitle("文件改名设置");
            dialogStage.initModality(Modality.APPLICATION_MODAL);
            dialogStage.initOwner(renameFilesButton.getScene().getWindow());
            dialogStage.setResizable(false);
            
            Scene scene = new Scene(root, 650, 700);
            dialogStage.setScene(scene);
            
            // 设置对话框图标
            try {
                dialogStage.getIcons().add(new Image(getClass().getResourceAsStream("/icons/app-icon.png")));
            } catch (Exception iconException) {
                System.err.println("无法加载对话框图标: " + iconException.getMessage());
            }
            
            // 设置数据和回调
            controller.setData(availableFields, submittedPeople, (ruleElements) -> {
                // 确认回调 - 直接执行改名
                executeRename(ruleElements, submittedPeople);
            });
            
            // 显示对话框
            dialogStage.showAndWait();
            
        } catch (Exception e) {
            showError("打开改名设置失败", "无法加载改名设置界面: " + e.getMessage());
            e.printStackTrace();
        }
    }
    

    
    /**
     * 执行文件改名
     * 
     * @param ruleElements 规则元素列表
     * @param submittedPeople 已提交文件的人员列表
     */
    private void executeRename(java.util.List<FileRenameService.RuleElement> ruleElements, java.util.List<Person> submittedPeople) {
        showProgress("正在执行文件改名...");
        
        Task<java.util.List<FileRenameService.RenameResult>> renameTask = new Task<java.util.List<FileRenameService.RenameResult>>() {
            @Override
            protected java.util.List<FileRenameService.RenameResult> call() throws Exception {
                return fileRenameService.executeRename(submittedPeople, ruleElements);
            }
            
            @Override
            protected void succeeded() {
                java.util.List<FileRenameService.RenameResult> results = getValue();
                
                Platform.runLater(() -> {
                    hideProgress();
                    
                    // 统计结果
                    long successCount = results.stream().mapToLong(r -> r.isSuccess() ? 1 : 0).sum();
                    long failCount = results.size() - successCount;
                    
                    // 更新界面显示
                    updateScanResults(lastScanResult);
                    
                    // 显示结果
                    String message = String.format("改名完成!\n成功: %d 个\n失败: %d 个", successCount, failCount);
                    
                    if (failCount > 0) {
                        StringBuilder details = new StringBuilder(message);
                        details.append("\n\n失败详情:\n");
                        results.stream()
                            .filter(r -> !r.isSuccess())
                            .forEach(r -> details.append("• ").append(r.getOriginalName())
                                .append(": ").append(r.getErrorMessage()).append("\n"));
                        
                        showError("改名完成（有失败）", details.toString());
                    } else {
                        showInfo("改名成功", message);
                    }
                    
                    updateStatus("文件改名完成: 成功 " + successCount + " 个, 失败 " + failCount + " 个");
                });
            }
            
            @Override
            protected void failed() {
                Platform.runLater(() -> {
                    hideProgress();
                    showError("改名失败", "执行改名时发生错误: " + getException().getMessage());
                });
            }
        };
        
        new Thread(renameTask).start();
    }
    
    /**
     * 导出报告
     * 
     * @param onlyUnsubmitted 是否只导出未提交人员
     */
    private void exportReport(boolean onlyUnsubmitted) {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("保存报告");
        fileChooser.setInitialFileName(getReportFileName(onlyUnsubmitted));
        fileChooser.getExtensionFilters().add(
            new FileChooser.ExtensionFilter("文本文件", "*.txt")
        );
        
        File saveFile = fileChooser.showSaveDialog(exportAllButton.getScene().getWindow());
        
        if (saveFile != null) {
            saveReportToFile(saveFile, onlyUnsubmitted);
        }
    }
    
    /**
     * 生成报告文件名
     * 
     * @param onlyUnsubmitted 是否只导出未提交人员
     * @return 文件名
     */
    private String getReportFileName(boolean onlyUnsubmitted) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
        String prefix = onlyUnsubmitted ? "未提交名单" : "提交情况报告";
        return prefix + "_" + timestamp + ".txt";
    }
    
    /**
     * 保存报告到文件
     * 
     * @param file 保存文件
     * @param onlyUnsubmitted 是否只导出未提交人员
     */
    private void saveReportToFile(File file, boolean onlyUnsubmitted) {
        try (java.io.OutputStreamWriter writer = new java.io.OutputStreamWriter(
                new java.io.FileOutputStream(file), java.nio.charset.StandardCharsets.UTF_8)) {
            // 写入报告头部
            writer.write("=== 文件提交情况报告 ===\n");
            writer.write("生成时间: " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "\n");
            writer.write("扫描文件夹: " + String.join(", ", foldersData) + "\n");
            writer.write("总人数: " + lastScanResult.getTotalCount() + "人\n\n");
            
            if (!onlyUnsubmitted) {
                // 写入统计信息
                writer.write("=== 统计结果 ===\n");
                writer.write("已提交: " + lastScanResult.getSubmittedCount() + "人 (" + lastScanResult.getSubmissionRateText() + ")\n");
                writer.write("未提交: " + lastScanResult.getUnsubmittedCount() + "人\n\n");
                
                // 写入已提交人员
                writer.write("=== 已提交人员 ===\n");
                for (Person person : lastScanResult.getSubmittedPeople()) {
                    String folderName = person.getFolderName();
                    if (folderName != null && !folderName.isEmpty()) {
                        writer.write("✅ " + person.getName() + " - " + person.getFileName() + " (" + folderName + ")\n");
                    } else {
                        writer.write("✅ " + person.getName() + " - " + person.getFileName() + "\n");
                    }
                }
                writer.write("\n");
            }
            
            // 写入未提交人员
            writer.write("=== 未提交人员 ===\n");
            for (Person person : lastScanResult.getUnsubmittedPeople()) {
                writer.write("❌ " + person.getName() + "\n");
            }
            
            updateStatus("报告已保存到: " + file.getAbsolutePath());
            showInfo("导出成功", "报告已保存到:\n" + file.getAbsolutePath());
            
        } catch (IOException e) {
            showError("导出失败", "保存文件时出错: " + e.getMessage());
        }
    }
    
    // ===== UI更新方法 =====
    
    /**
     * 更新界面状态
     */
    private void updateUI() {
        // 更新人员数量标签
        peopleCountLabel.setText("(共" + peopleData.size() + "人)");
        
        // 更新统计标签
        if (lastScanResult != null) {
            statisticsLabel.setText(lastScanResult.getSummaryText());
        } else {
            statisticsLabel.setText("已提交: 0人 (0%) | 未提交: 0人");
        }
        
        // 更新按钮状态
        scanButton.setDisable(peopleData.isEmpty() || foldersData.isEmpty());
        savePeopleButton.setDisable(peopleData.isEmpty()); // 有人员数据才能保存
        renameFilesButton.setDisable(lastScanResult == null || lastScanResult.getSubmittedPeople().isEmpty()); // 有匹配文件才能改名
        exportAllButton.setDisable(lastScanResult == null);
        exportUnsubmittedButton.setDisable(lastScanResult == null);
    }
    
    /**
     * 更新状态栏文本
     * 
     * @param message 状态消息
     */
    private void updateStatus(String message) {
        statusLabel.setText(message);
        System.out.println("状态: " + message);
    }
    
    /**
     * 显示进度指示器
     * 
     * @param message 进度消息
     */
    private void showProgress(String message) {
        progressIndicator.setVisible(true);
        updateStatus(message);
    }
    
    /**
     * 隐藏进度指示器
     */
    private void hideProgress() {
        progressIndicator.setVisible(false);
    }
    
    // ===== 对话框方法 =====
    
    /**
     * 显示错误对话框
     * 
     * @param title 标题
     * @param message 错误消息
     */
    private void showError(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        setDialogIcon(alert);
        alert.showAndWait();
        
        System.err.println("错误: " + title + " - " + message);
    }
    
    /**
     * 显示信息对话框
     * 
     * @param title 标题
     * @param message 信息消息
     */
    private void showInfo(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        setDialogIcon(alert);
        alert.showAndWait();
    }
    
    /**
     * 为对话框设置应用程序图标
     * 
     * @param dialog 对话框
     */
    private void setDialogIcon(Dialog<?> dialog) {
        try {
            // 设置对话框显示时的事件处理
            dialog.setOnShowing(event -> {
                try {
                    Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
                    if (stage != null && stage.getIcons().isEmpty()) {
                        stage.getIcons().add(new javafx.scene.image.Image(
                            getClass().getResourceAsStream("/icons/app-icon.png")
                        ));
                    }
                } catch (Exception e) {
                    System.out.println("无法设置对话框图标: " + e.getMessage());
                }
            });
        } catch (Exception e) {
            System.out.println("设置对话框图标监听器失败: " + e.getMessage());
        }
    }
} 